package model

import (
	"encoding/json"
	"time"

	"gorm.io/gorm"
	"openeuler.org/PilotGo/PilotGo-plugin-automation/internal/module/common/enum/workflow"
)

type Job struct {
	Id            int                `json:"id" gorm:"primaryKey;autoIncrement"`
	JobName       string             `json:"job_name"`
	JobId         string             `json:"job_id"`
	WorkflowId    int                `json:"workflow_id" gorm:"comment:作业编排ID"`
	UsageType     workflow.UsageType `json:"usage_type" gorm:"comment:编排业务类型"`
	OperationType string             `json:"operation_type" gorm:"comment:操作类型"`
	JobType       string             `json:"job_type"`
	ModifyUser    string             `json:"modify_user"`
	StartTime     int64              `json:"-"`
	EndTime       int64              `json:"-"`
	StartTimeStr  string             `json:"start_time" gorm:"-"`
	EndTimeStr    string             `json:"end_time" gorm:"-"`
	TotalTime     string             `json:"total_time"`
	ExecCode      string             `json:"exec_code"`
	JobStatus     string             `json:"job_status"`
	ExecHosts     string             `json:"exec_hosts"`
	ParentJobId   string             `json:"parent_job_id" gorm:"comment:父任务ID, 用于关联重试任务"`
	RetryCount    int                `json:"retry_count" gorm:"comment:重试次数"`
	RetryStep     int                `json:"retry_step" gorm:"comment:重试开始步骤"`
	RetryHosts    string             `json:"retry_hosts" gorm:"comment:重试的特定主机列表，逗号分隔，空表示所有主机"`
	RootJobId     string             `json:"root_job_id" gorm:"comment:根任务ID, 用于跟踪整个重试链"`
}

func (j *Job) AfterFind(tx *gorm.DB) (err error) {
	if j.StartTime > 0 {
		j.StartTimeStr = time.UnixMilli(j.StartTime).Format("2006-01-02 15:04:05")
	}
	if j.EndTime > 0 {
		j.EndTimeStr = time.UnixMilli(j.EndTime).Format("2006-01-02 15:04:05")
	}
	return nil
}

type JobParams struct {
	ID         int             `json:"id" gorm:"primaryKey;autoIncrement"`
	WorkflowId int             `json:"workflow_id"`
	JobId      string          `json:"job_id" gorm:"comment:作业Id"`
	Name       string          `json:"name" gorm:"comment:输入参数名称"`
	Type       string          `json:"type" gorm:"comment:参数类型"`
	Value      json.RawMessage `json:"value" gorm:"comment:参数值"`
}

type JobOutputParams struct {
	ID         int             `json:"id" gorm:"primaryKey;autoIncrement"`
	JobId      string          `json:"job_id" gorm:"comment:作业Id"`
	WorkflowId int             `json:"workflow_id"`
	Name       string          `json:"name" gorm:"comment:输出参数名称"`
	Type       string          `json:"type" gorm:"comment:参数类型"`
	Value      json.RawMessage `json:"value" gorm:"comment:参数值"`
}

type SubJob struct {
	ID            int               `json:"id" gorm:"primaryKey;autoIncrement"`
	JobId         string            `json:"job_id" gorm:"comment:作业Id"`
	WorkflowId    int               `json:"workflow_id" gorm:"comment:作业编排ID"`
	ScriptId      string            `json:"script_id" gorm:"comment:作业编排步骤脚本ID"`
	ScriptType    string            `json:"script_type" gorm:"not null;comment:脚本类型"`
	StepNum       int               `json:"step_num" gorm:"comment:作业编排步骤"`
	StepType      workflow.StepType `json:"step_type" gorm:"comment:作业编排类型"`
	ScriptParam   string            `json:"script_param" gorm:"comment:作业编排步骤脚本参数"`
	ScriptContent string            `json:"script_content" gorm:"comment:作业编排步骤脚本内容"`
	ScriptTimeout int               `json:"script_timeout" gorm:"comment:作业编排步骤脚本超时时间"`
}

type SubJobResult struct {
	ID           int    `json:"id" gorm:"primaryKey;autoIncrement"`
	JobId        string `json:"job_id" gorm:"comment:作业Id"`
	WorkflowId   int    `json:"workflow_id" gorm:"comment:作业编排ID"`
	IP           string `json:"ip" gorm:"comment:主机ip"`
	CurrentStep  int    `json:"current_step"  gorm:"comment:当前执行步骤"`
	ExecCode     string `json:"code" gorm:"comment:执行状态码"`
	SubJobStatus string `json:"sub_job_status" gorm:"comment:执行状态"`
	StartTime    int64  `json:"-" gorm:"comment:开始执行时间"`
	EndTime      int64  `json:"-" gorm:"comment:结束时间"`
	StartTimeStr string `json:"start_time" gorm:"-"`
	EndTimeStr   string `json:"end_time" gorm:"-"`
}

func (sjr *SubJobResult) AfterFind(tx *gorm.DB) (err error) {
	if sjr.StartTime > 0 {
		sjr.StartTimeStr = time.UnixMilli(sjr.StartTime).Format("2006-01-02 15:04:05")
	}
	if sjr.EndTime > 0 {
		sjr.EndTimeStr = time.UnixMilli(sjr.EndTime).Format("2006-01-02 15:04:05")
	}
	return nil
}

type SubJobStepResult struct {
	ID           int             `json:"id" gorm:"primaryKey;autoIncrement"`
	JobId        string          `json:"job_id" gorm:"comment:作业Id"`
	WorkflowId   int             `json:"workflow_id" gorm:"comment:作业编排ID"`
	IP           string          `json:"ip" gorm:"comment:主机ip"`
	StepNum      int             `json:"step_num" gorm:"comment:作业编排步骤"`
	SubJobStatus string          `json:"sub_job_status" gorm:"comment:步骤执行状态"`
	StartTime    int64           `json:"-" gorm:"comment:开始执行时间"`
	EndTime      int64           `json:"-" gorm:"comment:结束时间"`
	StartTimeStr string          `json:"start_time" gorm:"-"`
	EndTimeStr   string          `json:"end_time" gorm:"-"`
	Result       json.RawMessage `json:"result" gorm:"type:json;comment:步骤执行结果"`
}

func (sjsr *SubJobStepResult) AfterFind(tx *gorm.DB) (err error) {
	if sjsr.StartTime > 0 {
		sjsr.StartTimeStr = time.UnixMilli(sjsr.StartTime).Format("2006-01-02 15:04:05")
	}
	if sjsr.EndTime > 0 {
		sjsr.EndTimeStr = time.UnixMilli(sjsr.EndTime).Format("2006-01-02 15:04:05")
	}
	return nil
}

type Result struct {
	RetCode int    `json:"ret_code"`
	Stdout  string `json:"stdout"`
	Stderr  string `json:"stderr"`
	Message string `json:"message"`
}

type JobDTO struct {
	Job          Job               `json:"job"`
	InputParams  []JobParams       `json:"input_params"`
	OutputParams []JobOutputParams `json:"output_params"`
	SubJobs      []SubJob          `json:"sub_jobs"`
}

type TaskResumeRequest struct { // 恢复任务请求
	JobId   string `json:"job_id"`
	StepNum int    `json:"step_num"`
	Action  string `json:"action"`
	IP      string `json:"ip,omitempty"`
}

type TaskRetryRequest struct { // 重试任务请求
	JobId      string `json:"job_id" binding:"required"` // 原任务ID
	StepNum    int    `json:"step_num"`                  // 从指定步骤开始重试，0表示从头开始
	ReuseEnv   bool   `json:"reuse_env"`                 // 是否复用环境（保留已成功步骤状态）
	RetryHosts string `json:"retry_hosts,omitempty"`
}
